package com.starblink.search.result.ui.fragment.brand

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import com.starblink.android.basic.adapter.MutableAdapter
import com.starblink.android.basic.ext.string
import com.starblink.android.basic.extension.lazyOnNone
import com.starblink.android.basic.sensorsdata.spm.cfg.SpmPageDef
import com.starblink.android.basic.util.bus.FlowBus
import com.starblink.android.basic.util.bus.FlowConst
import com.starblink.android.basic.util.bus.bean.SubscribeBrandEvent
import com.starblink.android.basic.util.post.CommonMutateManage
import com.starblink.android.basic.widget.recycler.RefresherAndListCombiner
import com.starblink.android.common.databinding.CellSearchBrandBinding
import com.starblink.android.common.view.brand.BrandRecommendResultCell
import com.starblink.android.common.view.brand.BrandResultCell
import com.starblink.android.common.view.brand.SearchBrandRecommendModel
import com.starblink.basic.apollo.ext.ApolloValSetExt
import com.starblink.basic.apollo.ext.ApolloValSetExt.apolloValue
import com.starblink.basic.route.RoutePage
import com.starblink.rocketreserver.fragment.BrandVOF
import com.starblink.search.R
import com.starblink.search.config.SearchConfig
import com.starblink.search.databinding.FgmSearchStoreResultBinding
import com.starblink.search.result.ui.cell.GoodsEmptyCell
import com.starblink.search.result.ui.cell.GoodsTitleCell
import com.starblink.search.result.ui.fragment.BaseSearchFragment

class BrandResultFragment :
    BaseSearchFragment<FgmSearchStoreResultBinding, BrandResultVM>() {

    val adapter by lazyOnNone {
        MutableAdapter(viewModel.contentList).apply {
            addVhDelegate {
                BrandResultCell(
                    CellSearchBrandBinding.inflate(
                        layoutInflater,
                        it,
                        false
                    ),
                    pageDef = SpmPageDef.SearchBrandPage,
                    searchTerm = viewModel.contentSearch,
                    searchType = searchType,
                ) { merchant, position ->
                    merchant.brandId?.let { it1 ->
                        CommonMutateManage.subscribeOrNotBrand(
                            requireContext(), merchant.hasSub,
                            it1, brand = merchant,
                            resultCallback = {
                                ApolloValSetExt.setApolloVal<BrandVOF>(
                                    merchant, "hasSub",
                                    !merchant.hasSub
                                )
                                ApolloValSetExt.setApolloVal<BrandVOF>(
                                    merchant, "subNums",
                                    if (merchant.hasSub) (merchant.subNums!! + 1) else (merchant.subNums!! - 1)
                                )
                                refreshItem(position)

                            })
                    }
                }
            }
            addVhDelegate {
                BrandRecommendResultCell(
                    viewGroup = it,
                    searchTerm = viewModel.contentSearch,
                    searchType = searchType,
                    pageDef = SpmPageDef.SearchBrandPage,
                ) { merchant, position ->
                    merchant.brandId?.let { it1 ->
                        CommonMutateManage.subscribeOrNotBrand(
                            requireContext(), merchant.hasSub,
                            it1, brand = merchant,
                            resultCallback = {
                                ApolloValSetExt.setApolloVal<BrandVOF>(
                                    merchant, "hasSub",
                                    !merchant.hasSub
                                )
                                ApolloValSetExt.setApolloVal<BrandVOF>(
                                    merchant, "subNums",
                                    if (merchant.hasSub) (merchant.subNums!! + 1) else (merchant.subNums!! - 1)
                                )
                                refreshItem(position)
                            })
                    }
                }
            }
            addVhDelegate {
                GoodsEmptyCell(it)
            }
            addVhDelegate {
                GoodsTitleCell(it)
            }
        }
    }

    private val refreshCombiner by lazy {
        RefresherAndListCombiner(viewBinding.refresher, viewBinding.recycler)
    }

    override fun emptyMessage(): String = string(R.string.search_brand_empty_tip)

    override fun getViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ): FgmSearchStoreResultBinding = FgmSearchStoreResultBinding.inflate(inflater)


    override fun startObserve() {

        viewModel.contentLD.observe(this) {
            adapter.refreshAll()

            if (it) {
                refreshCombiner.finishLoadMore()
            } else {
                refreshCombiner.finishLoadMoreNoData()
            }
        }
    }

    override fun initData() {
        viewModel.contentSearch = arguments?.getString(QUERY_WORD, "") ?: ""
    }

    var searchType: String = ""

    override fun initView(view: View) {
        searchType =
            if (viewModel.searchWordSource == SearchConfig.SearchWordSourceConfig.O_TYPE_HOT) "trendingWord" else if (viewModel.searchWordSource == SearchConfig.SearchWordSourceConfig.O_TYPE_SHADING) "shadingWord" else "normal"

        viewBinding.recycler.layoutManager = LinearLayoutManager(requireContext())
        viewBinding.recycler.adapter = adapter

        refreshCombiner.onLoadMore {
//            if (viewModel.contentHasResult) {
//                viewModel.pageNo++
//                viewModel.loadData()
//            } else {
            viewModel.recPageNo++
            viewModel.loadRecStore()
//            }
        }
        FlowBus.with<SubscribeBrandEvent>(FlowConst.SUBSCRIBE_BRAND_EVENT).register(this) { event ->
            if (event.brandId != null) {
                viewModel.contentList.indexOfFirst { it is BrandVOF && event.brandId == it.brandId }
                    .takeIf { it > -1 }?.let {
                        var brand: BrandVOF = viewModel.contentList[it] as BrandVOF
                        changeBrandItem(brand, event, it)
                    }
                viewModel.contentList.indexOfFirst { it is SearchBrandRecommendModel && event.brandId == it.merchant.brandId }
                    .takeIf { it > -1 }?.let {
                        var brand: BrandVOF =
                            (viewModel.contentList[it] as SearchBrandRecommendModel).merchant
                        changeBrandItem(brand, event, it)
                    }
            }
        }
    }

    private fun changeBrandItem(
        brand: BrandVOF,
        event: SubscribeBrandEvent,
        it: Int
    ) {
        brand.apolloValue(
            "hasSub",
            event.hasSub
        )
//        brand.apolloValue(
//            "subNums",
//            if (brand.hasSub) (brand.subNums!! + 1) else (brand.subNums!! - 1)
//        )
        adapter.notifyItemChanged(it)
    }

    override fun initLoad() {

    }

    override fun onLazyInitData() {
        super.onLazyInitData()
        viewModel.loadData()
        refreshCombiner.setNoMoreData(false)
    }

    private fun refreshItem(position: Int) {
        adapter.notifyItemChanged(position)
    }


    companion object {

        const val QUERY_WORD = "query_word"
        private const val KEY_SEARCH_SCENE = "search_word_scene"

        fun newInstance(
            queryWord: String,
            searchScene: Int = 0,
        ) = BrandResultFragment().apply {
            arguments = bundleOf(
                QUERY_WORD to queryWord,
                KEY_SEARCH_SCENE to searchScene,
            )
        }

    }

    override fun spmPageId(): Int = SpmPageDef.SearchBrandPage

    override fun onResume() {
        super.onResume()
        if (arguments?.getInt(KEY_SEARCH_SCENE) == RoutePage.Search.SCENE.BRANDS.value) {
            pageExposure(
                SpmPageDef.SearchBrandPage,
                mapOf(
                    "searchTerm" to viewModel.contentSearch,
                    "searchType" to if (viewModel.searchWordSource == SearchConfig.SearchWordSourceConfig.O_TYPE_HOT) "trendingWord" else if (viewModel.searchWordSource == SearchConfig.SearchWordSourceConfig.O_TYPE_SHADING) "shadingWord" else "normal"
                )
            )
        }
    }
}